/*
 * @Author: call-me-xiao-hou 2322811647@qq.com
 * @Date: 2023-11-15 20:40:09
 * @LastEditors: call-me-xiao-hou 2322811647@qq.com
 * @LastEditTime: 2023-11-15 20:40:10
 * @FilePath: /2023-11-15/Sock.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "log.hpp"
#include "err.hpp"

static const int backlog = 5;

class Sock
{
public:
    void Socket()
    {
        _listensock = socket(AF_INET, SOCK_STREAM, 0);
        if (_listensock < 0)
        {
            logMessage(FATAL, "create socket error");
            exit(SOCKET_ERR);
        }

        int opt = 1;
        setsockopt(_listensock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof opt);
        logMessage(NORMAL, "create socket success");
    }

    void Bind(const uint16_t &port)
    {
        struct sockaddr_in local;
        memset(&local, 0, sizeof local);

        local.sin_family = AF_INET;
        local.sin_addr.s_addr = INADDR_ANY;
        local.sin_port = htons(port);

        int n = bind(_listensock, (struct sockaddr *)&local, sizeof local);
        if (n < 0)
        {
            logMessage(FATAL, "bind socket error");
            exit(BIND_ERR);
        }
        logMessage(NORMAL, "bind socket success");
    }

    void Listen()
    {
        int n = listen(_listensock, backlog);
        if (n < 0)
        {
            logMessage(FATAL, "listen socket error");
            exit(LISTEN_ERR);
        }

        logMessage(NORMAL, "listen socket success");
    }

    int Accept()
    {
        struct sockaddr_in peer;

        socklen_t len = sizeof(peer);
        int sock = accept(_listensock, (struct sockaddr *)&peer, &len);

        return sock;
    }

    int Fd()
    {
        return _listensock;
    }

    void Close()
    {
        if (_listensock > 0)
            close(_listensock);
    }

private:
    int _listensock;
};
